package by.epam.xslttask.validator;

import by.epam.xslttask.constants.ProductConstants;
import by.epam.xslttask.dto.ColorType;
import by.epam.xslttask.managers.LogManager;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ProductValidator {
    private static final String DATE_PATTERN = "(0[1-9]|[12]\\d|3[01])-(1[012]|0[1-9])-[12]\\d{3}";
    private static final String MODEL_PATTERN = "[A-Za-z]{2}\\d{3}";
    private Map<String, String> errors;

    public ProductValidator() {
        errors = new HashMap();
    }

    public boolean validate(String name, String producer, String model,
                            String date, String color, String price, AtomicBoolean error) {
        if(name != null && producer != null && model != null
                && date != null && color != null && price != null) {
            boolean valName = validateName(name, error);
            boolean valProducer = validateProducer(producer, error);
            boolean valModel = validateModel(model, error);
            boolean valDate = validateDate(date, error);
            boolean valColor = validateColor(color, error);
            boolean valPrice = validatePrice(price, error);

            return valProducer && valModel && valName && valDate && valColor && valPrice;
        }
        else {
            return true;
        }
    }

    private boolean validateProducer(String producer, AtomicBoolean error) {
        if(producer == null || producer.isEmpty()) {
            String message = LogManager.getProperty(LogManager.EMPTY_PRODUCER);
            errors.put(ProductConstants.PRODUCER, message);
            error.set(true);
            return false;
        }
        return true;
    }
    
    private boolean validateModel(String model, AtomicBoolean error) {
        if(model == null || model.isEmpty()) {
            String message = LogManager.getProperty(LogManager.EMPTY_MODEL);
            errors.put(ProductConstants.MODEL, message);
            error.set(true);
            return false;
        }
        else {
            Pattern pattern = Pattern.compile(MODEL_PATTERN);
            Matcher m = pattern.matcher(model);
            boolean res = m.matches();
            if(!res) {
                String message = LogManager.getProperty(LogManager.INVALID_MODEL);
                errors.put(ProductConstants.MODEL, message);
                error.set(true);
            }
            return res;
        }

    }

    private boolean validateName(String name, AtomicBoolean error) {
        if(name == null || name.isEmpty()) {
            String message = LogManager.getProperty(LogManager.EMPTY_NAME);
            errors.put(ProductConstants.NAME, message);
            error.set(true);
            return false;
        }
        return true;
    }
    
    private boolean validateDate(String date, AtomicBoolean error) {
        if(date == null || date.isEmpty()) {
            String message = LogManager.getProperty(LogManager.EMPTY_DATE);
            errors.put(ProductConstants.DATE, message);
            error.set(true);
            return false;
        }
        else {
            Pattern pattern = Pattern.compile(DATE_PATTERN);
            Matcher m = pattern.matcher(date);
            boolean res = m.matches();
            if(!res) {
                String message = LogManager.getProperty(LogManager.INVALID_DATE);
                errors.put(ProductConstants.DATE, message);
                error.set(true);
            }
            return res;
        }
    }
    
    private boolean validateColor(String color, AtomicBoolean error) {
        if(color == null || color.isEmpty()) {
            String message = LogManager.getProperty(LogManager.EMPTY_COLOR);
            errors.put(ProductConstants.COLOR, message);
            error.set(true);
            return false;
        }
        else {
            try {
                ColorType.valueOf(color);
                return true;
            }
            catch (IllegalArgumentException ex) {
                String message = LogManager.getProperty(LogManager.INVALID_COLOR);
                errors.put(ProductConstants.COLOR, message);
                error.set(true);
                return false;
            }
        }
    }
    
    private boolean validatePrice(String price, AtomicBoolean error) {
        if(price == null || price.isEmpty()) {
            String message = LogManager.getProperty(LogManager.EMPTY_PRICE);
            errors.put(ProductConstants.PRICE, message);
            error.set(true);
            return false;
        }
        else {
            try{
                int intPrice = Integer.parseInt(price);
                if(intPrice <= 0) {
                    String message = LogManager.getProperty(LogManager.INVALID_PRICE);
                    errors.put(ProductConstants.PRICE, message);
                    error.set(true);
                    return false;
                }
                else {
                    return true;
                }
            }
            catch (NumberFormatException ex) {
                String message = LogManager.getProperty(LogManager.INVALID_PRICE);
                errors.put(ProductConstants.PRICE, message);
                error.set(true);
                return false;
            }
            
        }
    }
    
    public String getNameError() {
        return errors.get(ProductConstants.NAME);
    }
    
    public String getProducerError() {
        return errors.get(ProductConstants.PRODUCER);
    }
    
    public String getModelError() {
        return errors.get(ProductConstants.MODEL);
    }
    
    public String getDateError() {
        return errors.get(ProductConstants.DATE);
    }
    
    public String getColorError() {
        return errors.get(ProductConstants.COLOR);
    }
    
    public String getPriceError() {
        return errors.get(ProductConstants.PRICE);
    }
    
}
